package com.eerl.pdev;

import com.eerl.pdev.debug.EDebugShow;
import com.eerl.pdev.debug.EVarWatch;
import com.eerl.pdev.ori.erl.ErlCommon;
import com.eerl.pdev.ori.erl.OriErlangNode;
import com.eerl.pdev.util.Notice;
import com.eerl.pdev.werl.msg.handler.BindVarHandler;
import com.intellij.openapi.components.Service;
import com.intellij.openapi.project.Project;

import java.util.HashMap;
import java.util.Map;

@Service(Service.Level.PROJECT)
public final class ProjectContainer {

    private Project project;
    private final Map<Class, Object> map = new HashMap<>();

    private int counter = 1;

    public ProjectContainer(Project project) {
        this.project = project;
    }

    public static ProjectContainer getInstance(Project project) {
        return project.getService(ProjectContainer.class);
    }

    public <T> T get(Class<T> tClass) {
        Object o = map.get(tClass);
        if (o == null) {
            lazyLoad(tClass);
        }
        return tClass.cast(map.get(tClass));
    }

    public void add(Object o) {
        map.put(o.getClass(), o);
    }
    
    private <T> void lazyLoad(Class<T> tClass) {
        if (tClass.equals(OriErlangNode.class)) {
            // String remoteHost = "cahx_xlllocal_1@127.0.0.1";
            // String remoteCookie = "s98zksns891jsj";
            String remoteHost = MySettingsState.getInstance().ERL_NODE_NAME;
            String remoteCookie = MySettingsState.getInstance().ERL_NODE_COOKIE;
            // erl node init
            if (remoteCookie == null || remoteHost == null) {
                Notice.showDialogMessage("链接失败", "erl 节点连接失败，确保在设置配置了远程节点名称和节点cookie");
                return;
            }
            OriErlangNode node = new OriErlangNode(project, remoteCookie, remoteHost);
            node.addMsgHandler(get(BindVarHandler.class));
            ErlCommon.autoCodeStrCompileAndLoad(project, node);
            add(node);
        } else if (tClass.equals(BindVarHandler.class)) {
            // erl var printer
            BindVarHandler bindVarHandler = new BindVarHandler(project);
            add(bindVarHandler);
        } else if(tClass.equals(EDebugShow.class)) {
            EDebugShow userData = (new EDebugShow());
            userData.setProject(project);
            add(userData);
        } else if(tClass.equals(EVarWatch.class)) {
            add(new EVarWatch(project));
        } else {
            T service = project.getService(tClass);
            add(service);
        }
    }

    public void remove(Class c) {
        map.remove(c);
    }

    public int getCounter() {
        return counter++;
    }
}
